﻿Imports System.Drawing.Drawing2D

Partial Class Puzzle

    Sub DrawGiven(ByVal Rect As Rectangle, ByVal s As String, ByVal Invert As Boolean)
        If Invert Then
            Gfx.DrawString(s, HintFont(1), Brushes.White, Rect, Centered)
        Else
            Gfx.DrawString(s, HintFont(1), Brushes.Black, Rect, Centered)
        End If
    End Sub

    Sub DrawGivenRegion(ByVal Cell As Cell, ByVal s As String)
        Gfx.DrawString(s, HintFont(2), Brushes.Black, Cell.Rect, LeftAligned)
    End Sub

    Sub Fill(ByVal Cell As Cell, ByVal Type As Integer)
        Dim R = Cell.Rect
        R.Inflate(-1, -1)
        Dim Col As Color
        If Type = 1 Then Col = Color.Black
        If Type = 2 Then Col = Color.FromArgb(240, Color.White)
        Gfx.FillRectangle(New SolidBrush(Col), R)
    End Sub

    Sub DrawFound(ByVal Cell As Cell, ByVal s As String)
        Gfx.DrawString(s, FoundFont, New SolidBrush(Color.FromArgb(192, Color.OrangeRed)), Cell.Rect, Centered)
    End Sub

    Sub DrawBorder(ByVal Cell As Cell)
        Gfx.DrawRectangle(New Pen(Color.Silver, 2), Cell.Rect)
    End Sub

    Sub DrawCircle(ByVal Cell As Cell)
        Dim R = Cell.Rect
        Gfx.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        Gfx.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
        R.Inflate(-4, -4)
        Gfx.DrawEllipse(New Pen(Color.Black, 2), R)
        Gfx.SmoothingMode = Drawing2D.SmoothingMode.Default
        Gfx.PixelOffsetMode = Drawing2D.PixelOffsetMode.Default
    End Sub

    Sub DrawBorders(ByVal Cell As Cell, ByVal ParamArray Bool() As Boolean)
        Dim R = Cell.Rect
        Dim Pen As New Pen(Brushes.Black, 2)
        If Not Bool(0) Then Gfx.DrawLine(Pen, R.Left, R.Top, R.Left, R.Bottom)
        If Not Bool(1) Then Gfx.DrawLine(Pen, R.Left, R.Top, R.Right, R.Top)
        If Not Bool(2) Then Gfx.DrawLine(Pen, R.Right, R.Top, R.Right, R.Bottom)
        If Not Bool(3) Then Gfx.DrawLine(Pen, R.Left, R.Bottom, R.Right, R.Bottom)
    End Sub

    Sub DrawHighlight(ByVal Cell As Cell)
        Dim Rect = Cell.Rect
        Rect.Inflate(-1, -1)
        Gfx.FillRectangle(New SolidBrush(Color.FromArgb(255, Color.Yellow)), Rect)
    End Sub

    Sub DrawPencilmarks(ByVal Cell As Cell, ByVal digits As String)
        Dim Rect = Cell.Rect
        Rect.Inflate(-Rect.Width / 12, -Rect.Height / 12)
        Dim i As Integer = 1
        For Each c In digits
            Dim SR As New Rectangle(Rect.Left, Rect.Top, Rect.Width \ 3, Rect.Height \ 3)
            SR.Offset(SR.Width * ((Val(i) - 1) Mod 3), SR.Height * ((Val(i) - 1) \ 3) + ((9 - digits.Count) \ 3) * SR.Height / 2)
            Gfx.DrawString(c, PencilmarkFont, New SolidBrush(Color.FromArgb(255, Color.Gray)), SR, Centered)
            i += 1
        Next
    End Sub

    Public Sub FillRect(ByVal x As Integer, ByVal y As Integer, ByVal w As Integer, ByVal h As Integer, ByVal col As Color)
        Gfx.FillRectangle(New SolidBrush(col), CellRect(x, y, w, h))
    End Sub

    Public Sub DrawRect(ByVal x As Integer, ByVal y As Integer, ByVal w As Integer, ByVal h As Integer, ByVal type As Integer)
        Dim Pen As New Pen(Color.Black, 2)
        Gfx.DrawRectangle(Pen, CellRect(x, y, w, h))
    End Sub

    Sub DrawGiven(ByVal Cell As Cell, ByVal s As String, ByVal Invert As Boolean)
        If Invert Then
            Gfx.DrawString(s, HintFont(1), Brushes.White, Cell.Rect, Centered)
        Else
            Select Case HintStyle
                Case 1 : Gfx.DrawString(s, HintFont(1), Brushes.Black, Cell.Rect, Centered)
                Case 2 : Gfx.DrawString(s, HintFont(2), Brushes.Black, Cell.Rect, LeftAligned)
            End Select
        End If
    End Sub

    Sub DrawCells()
        For Each Cell As Cell In Cells
            Dim e As New DrawCellArgs
            e.Cell = Cell
            DrawCell(e)
        Next
    End Sub

    Overridable Sub DrawCell(ByVal e As DrawCellArgs)
        DrawBorder(e.Cell)
        If e.Invert Then Fill(e.Cell, 1)
        If Selection.Contains(e.Cell) Then DrawHighlight(e.Cell) Else Fill(e.Cell, 2)
        If SupportsRegioning AndAlso Not Regions.Where(Function(r) r.Cells.Contains(e.Cell)).Any Then
            Gfx.FillRectangle(New HatchBrush(HatchStyle.LargeCheckerBoard, Color.FromArgb(32, Color.Black), Color.Transparent), e.Cell.Rect)
        End If
        If e.Cell.Given Then
            DrawGiven(e.Cell, If(e.Text <> "", e.Text, e.Cell.g), e.Invert)
        ElseIf e.Cell.Candidates.Count > 0 Then
            DrawPencilmarks(e.Cell, e.Cell.CandidateStr)
        Else
            DrawFound(e.Cell, If(e.Text <> "", e.Text, e.Cell.f))
        End If
        If e.Circled Then DrawCircle(e.Cell)
    End Sub

    Sub DrawRegions()
        If Regions Is Nothing Then Exit Sub
        For Each Region In Regions
            Region.Draw()
        Next
    End Sub

End Class
